<?php
class FileSystemEntry
{
  /// CONSTANTES
  const TYPE_DIRECTORY  = 'TYPE_DIRECTORY';
  const TYPE_FILE       = 'TYPE_FILE';

  
  /// INTERNAL
  private $_path;
  private $_type;
  private $_children;
  
  // Permissions
  private $_read    = false;
  private $_write   = false;
  private $_execute = false;
  
  // File info
  private $_mimeType;
  private $_size;
  private $_dateCreate;
  private $_dateUpdate;
  private $_owner;
  
  
  
  
  public function __construct( $path )
  {
    sfApplicationConfiguration::getActive()->loadHelpers('I18N');
    $this->setPath((string) $path);
  }
  
  
  ////////////////////////////////////////////////////////////////////// PUBLIC
  public function isDir()
  {
    return $this->_type === self::TYPE_DIRECTORY;
  }
  
  public function isFile()
  {
    return $this->_type === self::TYPE_FILE;
  }
  
  public function isReadable()
  {
    return $this->_read;
  }
  
  public function isWriteable()
  {
    return $this->_write;
  }
  
  public function isExecutable()
  {
    return $this->_execute;
  }
  
  public function getPath()
  {
    return $this->_path;
  }

  public function delete()
  {
    if( !$this->isWriteable() )
    {
      throw new FileSystemManagerException(__("Insufficient rights for delete file '%s'", null, 'jckckeditor'));
    }

    if(!unlink($this))
    {
      throw new FileSystemManagerException(__("Can't delete '%s'", null, 'jckckeditor'));
    }


  }
  
  public function repport()
  {
    if($this->isDir()) $type = 'd';
    if($this->isFile()) $type = 'f';
    $report = basename($this)."($type-"
      . ($this->isReadable()?'r':'')
      . ($this->isWriteable()?'w':'')
      . ($this->isExecutable()?'x':'')
      . ')';
    if( $this->isFile() ){
      $report .= ', Owner: '
      . $this->getOwner()
      .",\n size: "
      . $this->getFileSize()
      . '(' . round($this->getFileSize()/1024).' Ko )'
      .",\n type: "
      . $this->getMimeType()
      . ",\n Created at : "
      . $this->getDateCreate()
       . "\n Updated at : "
      . $this->getDateCreate()
      ;
    }

    
    return $report;
  }
  
  public function __toString()
  {
    return $this->getPath();
  }
  
  
  
  /**
   * Retourne le type mime.
   * 
   * @return  String  Le type mime sous la forme d'une chaine.
   */
  public function getMimeType()
  {
    return $this->_mimeType;
  }
  
  public function getFileSize()
  {
    return $this->_size;
  }
  
  public function getDateCreate()
  {
    return $this->_dateCreate;
  }
  
  public function getDateUpdate()
  {
    return $this->_dateUpdate;
  }
  
  public function getOwner()
  {
    return $this->_owner;
  }
  
  public function getChildren()
  {
    return $this->_children;
  }
  
  public function getContent($depth=1)
  {
    if( !$this->isDir() )
    {
      return false;
    }
    $cnt = dir($this->getPath());
    $this->_children = array();
    $depth--;
    while( false !== ($entry = $cnt->read()))
    {
      if( $entry == '.' || $entry == '..' )continue;
      
      $elem = new FileSystemEntry($this->getPath().'/'.$entry);
      $this->_children[] = $elem;
      if( $elem->isDir() && $depth > 0){
        $elem->getContent($depth);
      }
    }
  }
  
  
  
  /**
   * Définit le chemin de la ressource.
   * 
   * @param string $path
   * @throw FileSystemManagerException
   * @return void
   * @access protected
   */
  protected function setPath( $path )
  {

    if( !file_exists($path) )
    {
      throw new FileSystemManagerException(__("Unknow path '%s'", null, 'jckckeditor'));
    }
    $this->_path = $path;
    $this->checkPermissions();
    $this->checkType();
    if( $this->isFile() )
    {
      $this->checkFile();
    }
  }
  
  
  
  /**
   * Détection du type d'entrée.
   * 
   * @throw FileSystemManagerException
   */
  protected function checkType()
  {
    if( $this->_path === null )
    {
      throw new FileSystemManagerException(__("Variable 'path' is required", null, 'jckckeditor'));
    }
    
    if( is_dir($this->_path) )
    {
      $this->_type = self::TYPE_DIRECTORY;
    }
    
    else if( is_file($this->_path) )
    {
      $this->_type = self::TYPE_FILE;
    }
    
    else 
    {
      $this->_type = null;
      throw new FileSystemManagerException(__("Unknow type for path '%s'", null, 'jckckeditor'));
    }
  }
  
  /**
   * Détection des droits du fichier.
   * 
   * @throw FileSystemManagerException
   */
  protected function checkPermissions()
  {
    if( $this->_path === null )
    {
      throw new FileSystemManagerException(_("Variable 'path' is required.", null, 'jckckeditor'));
    }
    
    if( is_readable($this->_path) )
    {
      $this->_read = true;
    }
    
    if( is_writable($this->_path) )
    {
      $this->_write = true;
    }
    
    if( is_executable($this->_path) )
    {
      $this->_execute = true;
    }
  }
  
  
  protected function checkFile()
  {
    if( !$this->isReadable() ){
      throw new FileSystemManagerException(_("Insufficient rights for read file '%s'", null, 'jckckeditor'));
    }
    $finfo = finfo_open(FILEINFO_MIME);
    $this->_mimeType = finfo_file($finfo, $this->getPath());
    
    $this->_size = filesize($this->getPath());
    
    $this->_dateCreate = date('Y-m-d H:i:s', fileatime($this->getPath()));
    $this->_dateUpdate = date('Y-m-d H:i:s', filemtime($this->getPath()));

    // Tester la fonction (prb sous windows)
    if( function_exists("posix_getpwuid") ) {
        $infos = posix_getpwuid(fileowner($this->getPath()));
        $this->_owner = $infos['name'];
    } else {
        $this->_owner = "people";
    }
  }
  
  
  
}